package com.fjwt.gz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.core.model.security.GzUserDetails;
import com.fjwt.gz.core.utils.Base64;
import com.fjwt.gz.core.utils.WxUtil;
import com.fjwt.gz.db.dto.QrcodeRecordDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.QrcodeRecordVO;
import com.fjwt.gz.service.mapper.QrcodeRecordMapper;
import com.fjwt.gz.wxMp.applet.AppletWxChatService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 * 派券活动发放二维码生成历史记录表(目前仅针对派券奖品分配) 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class QrcodeRecordService extends ServiceImpl<QrcodeRecordMapper, QrcodeRecordEntity> {

    @Value("${isFormal.code}")
    private boolean isFormalCode;

    @Autowired
    private ActivityAwardService activityAwardService;

    @Autowired
    private AwardCouponService awardCouponService;

    @Autowired
    private AwardMchService awardMchService;

    @Autowired
    private QrcodeRecordMapper qrcodeRecordMapper;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private AgentAppService agentAppService;

    @Autowired
    private OssRecordService ossRecordService;

    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private AppletWxChatService  appletWxChatService;
    @Autowired
    private ActivityAppService activityAppService;
    @Autowired
    private AgentInfoService agentInfoService;

    @Autowired
    private AgentEmployeeService agentEmployeeService;

    /**
     * 获取机构下生成的领券二维码记录
     *
     * @param iPage
     * @param activityId 活动id
     * @return
     */
    public IPage<QrcodeRecordVO> getQrcodeRecordList(IPage iPage, Long activityId, String activityNo, String activityName, String createdAt) {
        return qrcodeRecordMapper.getQrcodeRecordList(iPage, activityId, activityNo, activityName, createdAt);
    }

    public IPage<QrcodeRecordVO> getAppQrcodeRecordList(IPage iPage, QrcodeRecordDTO qrcodeRecordDTO) {
        if (StrUtil.isNotBlank(qrcodeRecordDTO.getAgentNo())) {
            //查询当前机构下绑定的客户经理
            List<AgentEmployeeEntity> employeeEntityList = agentEmployeeService.list(AgentEmployeeEntity.gw()
                            .select(AgentEmployeeEntity::getAgentEmployeeId)
                    .eq(AgentEmployeeEntity::getAgentNo, qrcodeRecordDTO.getAgentNo()));
            if (CollUtil.isNotEmpty(employeeEntityList)) {
                List<Long> idList = employeeEntityList.stream().map(AgentEmployeeEntity::getAgentEmployeeId).toList();
                qrcodeRecordDTO.setAgentEmployeeList(idList);
            }
        }
        return qrcodeRecordMapper.getAppQrcodeRecordList(iPage, qrcodeRecordDTO);
    }

    /**
     * 获取活动所有领券二维码
     *
     * @param activityId 活动id
     * @return
     */
    public List<QrcodeRecordVO> getQrcodeRecordAllByActivityId(Long activityId) {
        ActivityEntity activityEntity = activityService.getById(activityId);
        if (ObjectUtils.isEmpty(activityEntity)) {
            throw new BizException("活动信息异常！");
        }
        ActivityAppEntity activityAppEntity = activityAppService.getOne(ActivityAppEntity.gw()
                .eq(ActivityAppEntity::getActivityId, activityId)
                .eq(ActivityAppEntity::getType, 1));

        AgentAppEntity agentAppEntity = agentAppService.getOne(AgentAppEntity.gw()
                .eq(AgentAppEntity::getAppId, activityAppEntity.getAppId()));
        //TODO 获取小程序配置信息 appId,appSecret
        SysConfig sysConfig = sysConfigService.getById(agentAppEntity.getAppId());
        JSONObject configObj = JSONObject.parseObject(sysConfig.getConfigVal());
        String appSecret = configObj.getString("appSecret");
        if (ObjectUtils.isEmpty(agentAppEntity) || StrUtil.isBlank(agentAppEntity.getAppId()) || StrUtil.isBlank(appSecret)) {
            throw new BizException("小程序配置信息有误！");
        }

        List<QrcodeRecordVO> qrcodeRecordList = qrcodeRecordMapper.getQrcodeRecordList(activityId, null, null, null);
        if (ObjectUtils.isNotEmpty(qrcodeRecordList)) {
            for (QrcodeRecordVO qrcodeRecordVO : qrcodeRecordList) {
                JSONObject json = new JSONObject();
                json.put("scene", "id=" + qrcodeRecordVO.getQrcodeRecordId() + "&activityId=" + qrcodeRecordVO.getActivityId());
                json.put("page", qrcodeRecordVO.getPathUrl());
                if (!isFormalCode){
                    json.put("env_version", "trial");
                }
                log.info("生成小程序码参数：{}，活动参数：{}，小程序配置信息：{}", json.toJSONString(), JSONObject.toJSONString(activityEntity), JSONObject.toJSONString(agentAppEntity));
                String code = appletWxChatService.getUnlimitedQRCode(json, agentAppEntity.getAppId(), appSecret);
                qrcodeRecordVO.setQrCode(code);
            }
        }
        List<QrcodeRecordVO> list = new ArrayList<>();
        list.addAll(qrcodeRecordList);
        return list;
    }

    /**
     * 获取详情
     * @param qrcodeRecordId 二维码记录id
     * @return
     */
    public QrcodeRecordVO getRecordDetail(Long qrcodeRecordId) {
        if(Objects.isNull(qrcodeRecordId)){
            throw new BizException("请求参数缺失！");
        }
        return qrcodeRecordMapper.getRecordDetail(qrcodeRecordId);
    }

    /**
     * 根据活动id获取当前活动下所有领券二维码
     * @param activityId 活动id
     * @return 领券二维码记录
     */
    public List<QrcodeRecordVO> getAllRecordByActivityId(Long activityId) {
        return qrcodeRecordMapper.getQrcodeRecordList(activityId, null, null, null);
    }

    /**
     * 新增二维码记录
     *
     * @param qrcodeRecordEntity 二维码记录
     * @return
     */
    public Long saveRecord(QrcodeRecordEntity qrcodeRecordEntity) {
        if (null == qrcodeRecordEntity.getActivityId() || null == qrcodeRecordEntity.getType() || null == qrcodeRecordEntity.getAppId()
                || null == qrcodeRecordEntity.getTagType() || null == qrcodeRecordEntity.getTagInfo()) {
            throw new BizException("请求参数缺失！");
        }
        if (qrcodeRecordEntity.getType() == 1) {
            if (null == qrcodeRecordEntity.getNumTotal() || null == qrcodeRecordEntity.getNumEveryone()) {
                throw new BizException("请求参数缺失！");
            }
            int i = this.checkCouponAward(qrcodeRecordEntity);
            if (0 == i) {
                throw new BizException("活动配置有误，请核实！");
            } else if (2 == i) {
                throw new BizException("设置领取奖品数量大于奖品剩余数量！");
            }
        }
        if (Constants.QRCODE_TAG_TYPE.ORG == qrcodeRecordEntity.getTagType()) {
            AgentInfoEntity agentInfo = agentInfoService.getAgentInfo(qrcodeRecordEntity.getTagInfo());
            if (agentInfo == null) {
                throw new BizException("所输入机构网点不存在！");
            }
        }
        // 判断商户是否属于可核销商户
        if (Constants.QRCODE_TAG_TYPE.MERCHANT == qrcodeRecordEntity.getTagType()) {
            // 查询活动配置卡券
            List<ActivityAwardEntity> list = activityAwardService.getBaseMapper().selectList(ActivityAwardEntity.gw()
                    .eq(ActivityAwardEntity::getActivityId, qrcodeRecordEntity.getActivityId()));
            // 查询卡券绑定可核销商户
            List<Long> awardIds = list.stream().map(ActivityAwardEntity::getAwardId).toList();
            LambdaQueryWrapper<AwardMchEntity> gw = AwardMchEntity.gw()
                    .in(AwardMchEntity::getAwardId, awardIds)
                    .eq(AwardMchEntity::getMchNo, qrcodeRecordEntity.getTagInfo());
            List<AwardMchEntity> awardMchEntityList = awardMchService.list(gw);
            if (ObjectUtils.isEmpty(awardMchEntityList)) {
                throw new BizException("该商户不属于可核销商户");
            }
        }
        qrcodeRecordEntity.setNumConsume(0);
        int insert = qrcodeRecordMapper.insert(qrcodeRecordEntity);
        if (insert > 0) {
            return qrcodeRecordEntity.getQrcodeRecordId();
        }
        return null;
    }

    /**
     * 生成二维码、或者查看二维码 (扫码领券)
     * 商户活动码
     *
     * @param qrcodeRecordId 二维码记录id
     * @return
     */
    public String getUnlimitedQRCode(Long qrcodeRecordId) {
        if(Objects.isNull(qrcodeRecordId)){
            throw new BizException("网络故障，请稍后重试！");
        }
        QrcodeRecordEntity entity = qrcodeRecordMapper.selectById(qrcodeRecordId);
        if (Objects.isNull(entity)) {
            throw new BizException("未找到生成参数！");
        }
        JSONObject json = new JSONObject();
        ActivityEntity activityEntity = activityService.getById(entity.getActivityId());
        // 生成其他渠道二维码
        if (Objects.isNull(activityEntity)) {
            throw new BizException("请核实活动配置！");
        }
        ActivityAppEntity  activityAppEntity = activityAppService.getOne(ActivityAppEntity.gw()
                .eq(ActivityAppEntity::getActivityId, entity.getActivityId())
                .eq(ActivityAppEntity::getType, 1));
        AgentAppEntity agentAppEntity = agentAppService.getOne(AgentAppEntity.gw()
                .eq(AgentAppEntity::getAppId, activityAppEntity.getAppId())
                .eq(AgentAppEntity::getType, 1));

        if (Objects.isNull(agentAppEntity)) {
            throw new BizException("小程序配置有误，！请联系管理员！");
        }
        String appId = agentAppEntity.getAppId();
        //TODO:获取 appSecret 从Redis中  表 t_sys_config
        SysConfig sysConfig = sysConfigService.getById(appId);
        JSONObject configObj = JSONObject.parseObject(sysConfig.getConfigVal());
        json.put("scene", "id=" + entity.getQrcodeRecordId() + "&activityId=" + entity.getActivityId());
        json.put("page", entity.getPathUrl());
        // 体验版需添加的参数
        if (!isFormalCode){
            json.put("env_version", "trial");
        }
//        json.put("check_path",false);
        log.info("生成小程序码参数：{}，活动参数：{}，小程序配置信息：{}", json.toJSONString(), JSONObject.toJSONString(activityEntity), JSONObject.toJSONString(agentAppEntity));
        String code = appletWxChatService.getUnlimitedQRCode(json, appId, configObj.getString("appSecret"));
        return code;
    }

    /**
     * 批量生成二维码
     * @param qrcodeRecordDTO
     * @param bizType
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject batchCreateQrCode(QrcodeRecordDTO qrcodeRecordDTO, String bizType) {
        // 获取导入数据
        List<QrcodeRecordEntity> qrcodeRecordList = getQrcodeRecordToList(qrcodeRecordDTO.getOssFileUrl(), bizType);
        if (CollUtil.isEmpty(qrcodeRecordList)) {
            throw new BizException("导入文档为空！");
        }
    
        log.info("新增渠道码导入文件数据，共{}条", qrcodeRecordList.size());
    
        // 查询oss上传记录
        LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = OssRecordEntity.gw();
        ossRecordWrapper.eq(OssRecordEntity::getOssUrl,qrcodeRecordDTO.getOssFileUrl());
        ossRecordWrapper.eq(OssRecordEntity::getUploadType, Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
        OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(ossRecordWrapper);
        if(Objects.isNull(recordEntity)){
            throw new BizException("导入失败！未找到导入文件");
        }
    
        List<QrcodeRecordEntity> addQrcodeRecordList = new ArrayList<>();
        List<QrcodeRecordEntity> failQrcodeRecordList = new ArrayList<>();

        //失败商户号及原因结果
        List<String> errorRecord = new ArrayList<>();
        Long activityId = qrcodeRecordDTO.getActivityId();
        Long createId = qrcodeRecordDTO.getCreateId();
    
        // 查询此活动下已生成的二维码
        List<QrcodeRecordVO> allRecord = getAllRecordByActivityId(activityId);
        Set<String> tagInfoSet = allRecord.stream().map(QrcodeRecordVO::getTagInfo).collect(Collectors.toSet());
    
        // 提前查询活动配置卡券和可核销商户
        LambdaQueryWrapper<ActivityAwardEntity> awardWrapper = ActivityAwardEntity.gw()
            .eq(ActivityAwardEntity::getActivityId, activityId);
        List<ActivityAwardEntity> activityAwardList = activityAwardService.getBaseMapper().selectList(awardWrapper);
        List<Long> awardIds = activityAwardList.stream().map(ActivityAwardEntity::getAwardId).collect(Collectors.toList());
    
        // 查询所有相关可核销商户
        Map<String, List<AwardMchEntity>> awardMchMap = new HashMap<>();
        if (!awardIds.isEmpty()) {
            LambdaQueryWrapper<AwardMchEntity> mchWrapper = AwardMchEntity.gw().in(AwardMchEntity::getAwardId, awardIds);
            List<AwardMchEntity> allMchList = awardMchService.list(mchWrapper);
            awardMchMap = allMchList.stream().collect(Collectors.groupingBy(AwardMchEntity::getMchNo));
        }
    
        for (QrcodeRecordEntity qrcodeRecord : qrcodeRecordList) {
            if (StringUtils.isBlank(qrcodeRecord.getTagInfo())) {
                continue;
            }
            if (tagInfoSet.contains(qrcodeRecord.getTagInfo())) {
                log.error("商户号：{}，已存在，请勿重复导入！", qrcodeRecord.getTagInfo());
                errorRecord.add("商户号：" + qrcodeRecord.getTagInfo() + "，已存在，请勿重复导入！");
                failQrcodeRecordList.add(qrcodeRecord);
                continue;
            }
    
            qrcodeRecord.setTagType(0);
            qrcodeRecord.setType(1);
            qrcodeRecord.setActivityId(activityId);
    
            int checkResult = this.checkCouponAward(qrcodeRecord);
            if (checkResult == 0) {
                log.error("活动配置有误，请核实！");
                errorRecord.add("商户号：" + qrcodeRecord.getTagInfo() + "，活动配置有误，请核实！");
                failQrcodeRecordList.add(qrcodeRecord);
                continue;
            } else if (checkResult == 2) {
                log.error("设置领取奖品数量大于奖品剩余数量！");
                errorRecord.add("商户号：" + qrcodeRecord.getTagInfo() + "，设置领取奖品数量大于奖品剩余数量！");
                failQrcodeRecordList.add(qrcodeRecord);
                continue;
            }
    
            // 检查商户是否可核销
            List<AwardMchEntity> mchList = awardMchMap.getOrDefault(qrcodeRecord.getTagInfo(), Collections.emptyList());
            if (mchList.isEmpty()) {
                log.error("该商户不属于可核销商户");
                errorRecord.add("商户号：" + qrcodeRecord.getTagInfo() + "，该商户不属于可核销商户");
                failQrcodeRecordList.add(qrcodeRecord);
                continue;
            }
    
            qrcodeRecord.setCreatedAt(new Date());
            qrcodeRecord.setNumConsume(0);
            qrcodeRecord.setAppId(qrcodeRecordDTO.getAppId());
            qrcodeRecord.setCreatedUid(createId);
            addQrcodeRecordList.add(qrcodeRecord);
        }
    
        if (!errorRecord.isEmpty()) {
            throw new BizException("导入失败！有以下商户校验不通过：" + String.join("; ", errorRecord));
        }
    
        saveBatch(addQrcodeRecordList);
    
        JSONObject json = new JSONObject();
        json.put("successList", addQrcodeRecordList);
        json.put("failList", failQrcodeRecordList);
    
        return json;
    }
    
    /**
     * oss文件导入渠道
     * @return
     */
    public List<QrcodeRecordEntity> getQrcodeRecordToList(String ossFileUrl, String bizType) {
        File file = null;
        try {
            String safeFileName = String.format("%d.xlsx", DateUtil.date().getTime());
            file = FileUtil.file("./temp/", safeFileName);
            HttpUtil.downloadFile(ossFileUrl, file);
    
            LambdaQueryWrapper<OssRecordEntity> ossRecordWrapper = OssRecordEntity.gw();
            ossRecordWrapper.eq(OssRecordEntity::getOssUrl, ossFileUrl);
            ossRecordWrapper.eq(OssRecordEntity::getUploadType, Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
            OssRecordEntity recordEntity = ossRecordService.getBaseMapper().selectOne(ossRecordWrapper);
    
            OssRecordEntity ossRecordEntity = new OssRecordEntity();
            ossRecordEntity.setBizType(bizType);
            ossRecordEntity.setOssUrl(ossFileUrl);
            ossRecordEntity.setFileSize(file.length());
            ossRecordEntity.setUploadType(Constants.OSS_UPLOAD_TYPE.ACTIVITY_CHANNEL_IMPORT);
            ossRecordEntity.setSysUserId(GzUserDetails.getCurrentUserDetails().getSysUser().getSysUserId());
            ossRecordEntity.setCreatedAt(new Date());
    
            if (recordEntity == null) {
                ossRecordService.save(ossRecordEntity);
            } else {
                ossRecordEntity.setOssRecordId(recordEntity.getOssRecordId());
                ossRecordService.getBaseMapper().updateById(ossRecordEntity);
            }
    
            try (ExcelReader reader = ExcelUtil.getReader(file)) {
                reader.addHeaderAlias("团长商户号", "tagInfo");
                reader.addHeaderAlias("单客户可领", "numEveryone");
                reader.addHeaderAlias("配券张数", "numTotal");
    
                return reader.readAll(QrcodeRecordEntity.class);
            }
        } catch (Exception e) {
            log.error("文件下载或读取失败: {}", e.getMessage(), e);
            throw new BizException("文件下载或读取失败");
        } finally {
            if (file != null) {
                FileUtil.del(file);
            }
        }
    }

    /**
     * 校验奖品数量
     *
     * @param qrcodeRecordEntity 二维码记录
     * @return
     */
    public int checkCouponAward(QrcodeRecordEntity qrcodeRecordEntity) {
        List<ActivityAwardEntity> list = activityAwardService.getBaseMapper().selectList(ActivityAwardEntity.gw()
                .eq(ActivityAwardEntity::getActivityId, qrcodeRecordEntity.getActivityId()));
        log.info("活动id：{}，活动奖品信息：{}", qrcodeRecordEntity.getActivityId(), JSONObject.toJSONString(list));
        if (list.isEmpty()) {
            return 0;
        }
        AwardCouponEntity entity = awardCouponService.getById(list.get(0).getAwardId());
        log.info("卡券奖品信息：{}", JSONObject.toJSONString(entity));
        log.info("设置总领取数量：{}，每人可领取数量：{}", qrcodeRecordEntity.getNumTotal(), qrcodeRecordEntity.getNumEveryone());
        if (null == entity) {
            return 0;
        }
        // 剩余数量
        int surplusNum = entity.getCouponNum() - entity.getCouponGet();
        int sum = qrcodeRecordEntity.getNumTotal();
        if (sum > surplusNum) {
            return 2;
        }
        return 1;
    }

    /**
     * 邀约生成小程序二维码码
     * @return
     */
    public String getInviterUnlimitedQRCode(String appId, Long fansId, String pathUrl) {
        if(StringUtils.isEmpty(appId) || null == fansId){
            throw new BizException("网络故障，请稍后重试！");
        }
        LambdaQueryWrapper<AgentAppEntity> agentAppQueryWrapper = AgentAppEntity.gw();
        agentAppQueryWrapper.eq(AgentAppEntity::getAppId, appId).eq(AgentAppEntity::getType, 1);
        AgentAppEntity liteEntity = agentAppService.getBaseMapper().selectOne(agentAppQueryWrapper);
        if (null == liteEntity) {
            throw new BizException("小程序配置信息有误请核实！");
        }
        JSONObject json = new JSONObject();
        json.put("scene", "inviterId=" + fansId + "&inviterType=6");
        json.put("page", StringUtils.isNotEmpty(pathUrl) ? pathUrl : null);
        if (!isFormalCode){
            json.put("env_version", "trial");
        }
        log.info("生成小程序码参数：{}，小程序配置信息：{}", json.toJSONString(), JSONObject.toJSONString(liteEntity));
        SysConfig sysConfig = sysConfigService.getById(appId);
        JSONObject configVal = JSONObject.parseObject(sysConfig.getConfigVal());
        byte[] bytes = WxUtil.getUnlimitedQRCode(json, liteEntity.getAppId(), configVal.getString("appSecret"));
        return Base64.encodeBase64String(bytes);
    }

    public ResponseEntity<StreamingResponseBody> getQrcodeToFile(Long activityId) {
        List<QrcodeRecordVO> list = this.getQrcodeRecordAllByActivityId(activityId);
        StreamingResponseBody stream = out -> {
            try (ZipOutputStream zipOut = new ZipOutputStream(out)) {
                for (QrcodeRecordVO qrcodeRecordVO : list) {
                    String fileName = qrcodeRecordVO.getQrcodeRecordId() + "_" + qrcodeRecordVO.getTagInfo() + ".png";
                    // 处理Base64数据
                    String pureBase64 = qrcodeRecordVO.getQrCode().replaceFirst("^data:[^;]+;base64,", "");
                    byte[] imageBytes = java.util.Base64.getDecoder().decode(pureBase64);
                    // 添加到ZIP
                    zipOut.putNextEntry(new ZipEntry(fileName));
                    zipOut.write(imageBytes);
                    zipOut.closeEntry();
                }
                zipOut.finish();
            }
        };

        try {
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\"" + URLEncoder.encode("领券码.zip", "UTF-8") + "\"")
                    .header("X-Content-Type-Options", "nosniff")  // 防止MIME类型嗅探
                    .header("Content-Security-Policy", "default-src 'none'")  // 更严格的CSP策略
                    .header("X-Frame-Options", "DENY")  // 防止点击劫持
                    .header("X-XSS-Protection", "1; mode=block")  // XSS保护
                    .header("Cache-Control", "no-cache, no-store, must-revalidate")  // 禁用缓存
                    .header("Pragma", "no-cache")  // HTTP/1.0 向后兼容
                    .header("Expires", "0")  // 立即过期
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)  // 明确指定二进制流类型
                    .body(stream);
        } catch (UnsupportedEncodingException e) {
            throw new BizException("转换异常！");
        }
    }

    /**
     * 新增二维码记录
     *
     * @param dto
     */
    public void insert(QrcodeRecordDTO dto, Long sysUserId) {
        QrcodeRecordEntity entity = BeanUtil.copyProperties(dto, QrcodeRecordEntity.class);
        entity.setCreatedUid(sysUserId);
        entity.setCreatedAt(new Date());
        boolean flag = save(entity);
        if (!flag) {
            log.error("新增失败！");
        }
    }
}
